package states;

import java.sql.SQLException;

import entity.Player;

import org.newdawn.slick.Color;
import org.newdawn.slick.Font;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.gui.AbstractComponent;
import org.newdawn.slick.gui.ComponentListener;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;
import org.newdawn.slick.tiled.TiledMap;

import ui.core.Button;
import ui.core.TextBox;
import ui.listener.ChangeGameStateListener;
import utils.ResourceManager;
import utils.SaveManager;

public class InGameState extends BasicGameState {

	public static final int ID = 3;

	TextBox textBox;
	final int PLAYERWIDTH = 32;
	final int PLAYERHEIGHT = 48;
	final int MOVE_NORTH = 3;
	final int MOVE_SOUTH = 0;
	final int MOVE_LEFT = 1;
	final int MOVE_RIGHT = 2;
	static GameContainer container;
	static StateBasedGame game;
	int SQMsize = 32;
	// int SQMsize = 16;
	int controlAnim = 0;
	boolean showMenu;
	// Map map;
	TiledMap map;
	static Player player;
	Button quitGameButton;
	Button saveGameButton;
	Font font;
	boolean flagbox = false;
	private boolean[][] blocked;
	private char[][] transition;
	private boolean[][] spawn;
	SaveManager svManager = new SaveManager();

	// public boolean checkBattle() throws SlickException {
	// if (map.getSquareValue(player.getX(), player.getY()) == 2) {
	// if (Math.random() > 0.95) {
	// game.enterState(BattleState.ID, new FadeOutTransition(
	// Color.black), new FadeInTransition(Color.black));
	// game.getState(BattleState.ID).init(container,game);
	// return true;
	// }
	// }
	// return false;
	// }
	public boolean checkBattle() throws SlickException {
		if (spawn[player.getX()][player.getY()]) {
			double rand = Math.random();
			if (rand > 0.8) {
				game.enterState(BattleState.ID, new FadeOutTransition(
						Color.black), new FadeInTransition(Color.black));
				game.getState(BattleState.ID).init(container, game);
				return true;
			}
		}
		return false;
	}

	// public void checkMapTransition() throws SlickException {
	// if (map.getSquareValue(player.getX(), player.getY()) == 3) {
	// String aux = "data/maps/Routex" + player.getXLocation() + "y"
	// + (player.getYLocation() + 1);
	// map = new Map(new Image(aux + ".png"), aux + ".txt");
	// // Setando em que mapa o player se encontra.
	// player.setYLocation(player.getYLocation() + 1);
	// player.setY(player.getY() + 18);
	//
	// } else if (map.getSquareValue(player.getX(), player.getY()) == 4) {
	// String aux = "data/maps/Routex" + player.getXLocation() + "y"
	// + (player.getYLocation() - 1);
	// map = new Map(new Image(aux + ".png"), aux + ".txt");
	// player.setYLocation(player.getYLocation() - 1);
	// player.setY(player.getY() - 18);
	//
	// } else if (map.getSquareValue(player.getX(), player.getY()) == 5) {
	// String aux = "data/maps/Routex" + (player.getXLocation() - 1) + "y"
	// + player.getYLocation();
	// map = new Map(new Image(aux + ".png"), aux + ".txt");
	// player.setXLocation(player.getXLocation() - 1);
	// player.setX(player.getX() + 18);
	//
	// } else if (map.getSquareValue(player.getX(), player.getY()) == 6) {
	// String aux = "data/maps/Routex" + (player.getXLocation() + 1) + "y"
	// + player.getYLocation();
	// map = new Map(new Image(aux + ".png"), aux + ".txt");
	// player.setXLocation(player.getXLocation() + 1);
	// player.setX(player.getX() - 18);
	// }
	// }

	public void showProfile() {
		ResourceManager.getImage("whiteBackground").draw(0, 0, 240, 100);
		ResourceManager.getImage(
				Integer.toString(player.getFirstPokemon().getId()) + "front").draw(
				3, 0, 1);
		font.drawString(80, 10, "Hp", new Color(0, 0, 0));
		font.drawString(80, 40, "Level", new Color(0, 0, 0));
		font.drawString(80, 70, "Exp", new Color(0, 0, 0));
		font.drawString(170, 10,
				Integer.toString(player.getFirstPokemon().getCurrentHp()),
				new Color(0, 0, 0));
		font.drawString(170, 40, Integer.toString(player.getFirstPokemon()
				.getLevel()), new Color(0, 0, 0));
		font.drawString(170, 70,
				Integer.toString(player.getFirstPokemon().getExperience()),
				new Color(0, 0, 0));
	}

	public void playerAnim(int position) {
		player.setImage(ResourceManager.getImage("playerImage").getSubImage(
				controlAnim * PLAYERWIDTH, position * PLAYERHEIGHT,
				PLAYERWIDTH, PLAYERHEIGHT));
		if (controlAnim != 3) {
			controlAnim += 1;
		} else {
			controlAnim = 0;
		}
	}

	public void checkMapTransition() throws SlickException {
		if (transition[player.getX()][player.getY()] == 'N') {
			map = new TiledMap("data/tmxMaps/"
					+ map.getMapProperty("nextN", "none"));
			initMap();
			player.setYLocation(player.getYLocation() + 1);
			System.out.println(player.getXLocation() + " - "
					+ player.getYLocation());
			player.setY(player.getY() + 18);
		} else if (transition[player.getX()][player.getY()] == 'S') {
			map = new TiledMap("data/tmxMaps/"
					+ map.getMapProperty("nextS", "none"));
			initMap();
			player.setYLocation(player.getYLocation() - 1);
			System.out.println(player.getXLocation() + " - "
					+ player.getYLocation());
			player.setY(player.getY() - 18);
		} else if (transition[player.getX()][player.getY()] == 'W') {
			map = new TiledMap("data/tmxMaps/"
					+ map.getMapProperty("nextW", "none"));
			initMap();
			player.setXLocation(player.getXLocation() - 1);
			System.out.println(player.getXLocation() + " - "
					+ player.getYLocation());
			player.setX(player.getX() + 18);
		}
		if (transition[player.getX()][player.getY()] == 'E') {
			map = new TiledMap("data/tmxMaps/"
					+ map.getMapProperty("nextE", "none"));
			initMap();
			player.setXLocation(player.getXLocation() + 1);
			System.out.println(player.getXLocation() + " - "
					+ player.getYLocation());
			player.setX(player.getX() - 18);
		}
	}

	@Override
	public void init(GameContainer container, StateBasedGame game)
			throws SlickException {
		textBox = new TextBox(container, 50, 400);
		this.font = ResourceManager.getFont("dejavuNormalFont");
		InGameState.container = container;
		InGameState.game = game;
		ResourceManager.getImage("blackBackground").setAlpha((float) 0.5);
		ResourceManager.getImage("whiteBackground").setAlpha((float) 0.5);
//		player = SaveManager.openGame(player);
		try {
			player = svManager.openGameDB();
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		// String aux = "data/maps/Routex" + player.getXLocation() + "y"
		// + player.getYLocation();
		// map = new Map(new Image(aux + ".png"), aux + ".txt");

		map = ResourceManager.getMap("x" + player.getXLocation() + "y"
				+ player.getYLocation() + "Map");
		initMap();

		saveGameButton = new Button(container,
				ResourceManager.getImage("saveGameButtonNormalImage"), 215, 150);
		saveGameButton.setMouseOverImage(ResourceManager
				.getImage("saveGameButtonOverImage"));
		saveGameButton.addListener(new ChangeGameStateListener(game,
				InGameState.ID));
		saveGameButton.addListener(new ComponentListener() {
			@Override
			public void componentActivated(AbstractComponent source) {
				try {
					svManager.saveGameDB(player);
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("Game Salvo");
				showMenu = false;
			}
		});

		quitGameButton = new Button(container,
				ResourceManager.getImage("quitGameButtonNormalImage"), 215, 200);

		quitGameButton.setMouseOverImage(ResourceManager
				.getImage("quitGameButtonOverImage"));

		quitGameButton.addListener(new ChangeGameStateListener(game,
				MainMenuState.ID));
		quitGameButton.addListener(new ComponentListener() {
			@Override
			public void componentActivated(AbstractComponent source) {
				try {
					InGameState.game.getState(MainMenuState.ID).init(
							InGameState.container, InGameState.game);
				} catch (SlickException e) {
					e.printStackTrace();
				}
			}
		});
		showMenu = false;
	}

	public void initMap() {
		int FORE = 1;
		int TRANSITION = 3;
		int SPAWN = 4;
		spawn = new boolean[map.getWidth()][map.getHeight()];
		transition = new char[map.getWidth()][map.getHeight()];
		blocked = new boolean[map.getWidth()][map.getHeight()];
		for (int xAxis = 0; xAxis < map.getWidth(); xAxis++) {
			for (int yAxis = 0; yAxis < map.getHeight(); yAxis++) {
				int tileID = map.getTileId(xAxis, yAxis, FORE);
				int tileID2 = map.getTileId(xAxis, yAxis, TRANSITION);
				int tileID3 = map.getTileId(xAxis, yAxis, SPAWN);
				if (tileID != 0) {
					blocked[xAxis][yAxis] = true;
				}
				if (tileID2 != 0) {
					char value = map.getTileProperty(tileID2, "direction",
							"none").toCharArray()[0];
					transition[xAxis][yAxis] = value;
				}
				if (tileID3 != 0) {
					spawn[xAxis][yAxis] = true;
				}
			}
		}
	}

	@Override
	public void render(GameContainer container, StateBasedGame game, Graphics g)
			throws SlickException {
		// map.getImage().draw(0, 0, 2);
		map.render(0, 0, 0);
		map.render(0, 0, 1);
		map.render(0, 0, 4);
		player.getImage().draw(player.getX() * SQMsize,
				(player.getY() * SQMsize) - 15);
		map.render(0, 0, 2);
		// map.getImage().getSubImage(player.getX()*SQMsize - 8*SQMsize,
		// player.getY()*SQMsize - 6*SQMsize, 320, 320).draw(0, 0, 3);
		// player.getImage().draw(380,
		// 260, (float)1.5);
		//
		if (flagbox)
			textBox.render(container, g);
		if (showMenu) {
			saveGameButton.render(container, g);
			quitGameButton.render(container, g);
			showProfile();
		}
	}

	private boolean isBlocked(float x, float y) {
		int xBlock = (int) x;
		int yBlock = (int) y;
		return blocked[xBlock][yBlock];
	}

	@Override
	public void update(GameContainer container, StateBasedGame game, int delta)
			throws SlickException {
		Input input = container.getInput();

		if (input.isKeyPressed(Input.KEY_SPACE)) {
			if (transition[player.getX()][player.getY() - 1] == 'H') {
				if (flagbox) {
					flagbox = false;
				} else {
					flagbox = true;
				}
				textBox.setText("Hello my dear trainer, do you want to heal your Pokemon?");

				textBox.setButton1(container, true, new ComponentListener() {
					@Override
					public void componentActivated(AbstractComponent source) {
						player.getFirstPokemon().setCurrentHp(
								player.getFirstPokemon().getHp());
						flagbox = false;
					}
				}, "Yes");
				textBox.setButton2(container, true, new ComponentListener() {

					@Override
					public void componentActivated(AbstractComponent source) {
						// TODO Auto-generated method stub
						flagbox = false;
					}
				}, "No");
			}
		}

		if (input.isKeyPressed(Input.KEY_ESCAPE)) {
			if (showMenu) {
				showMenu = false;
			} else {
				showMenu = true;
			}
		}
		if (input.isKeyPressed(Input.KEY_1)) {
			player.getFirstPokemon().setCurrentHp(
					player.getFirstPokemon().getCurrentHp() + 10);
		}
		if (input.isKeyPressed(Input.KEY_2)) {

		}
		if (input.isKeyDown(Input.KEY_3)) {
			player.getFirstPokemon().adicionarExperiencia(1);
		}

		if (input.isKeyPressed(Input.KEY_W)) {
			if ((player.getY() - 1) >= 0) {
				if (!isBlocked(player.getX(), player.getY() - 1)) {
					// if (map.getSquareValue(player.getX(), player.getY() - 1)
					// != 1
					// && map.getSquareValue(player.getX(), player.getY() - 1)
					// != 7) {
					player.moveNorth();
					playerAnim(MOVE_NORTH);
					checkBattle();
					checkMapTransition();
					// }
				}
			}
		}
		if (input.isKeyPressed(Input.KEY_S)) {
			if ((player.getY() + 1) < 20) {
				if (!isBlocked(player.getX(), player.getY() + 1)) {
					// if (map.getSquareValue(player.getX(), player.getY() + 1)
					// != 1) {
					player.moveSouth();
					playerAnim(MOVE_SOUTH);
					// if (map.getSquareValue(player.getX(), player.getY()) ==
					// 7) {
					// player.moveSouth();
					// }
					checkBattle();
					checkMapTransition();
					// }
				}
			}
		}
		if (input.isKeyPressed(Input.KEY_A)) {
			if ((player.getX() - 1) >= 0) {
				if (!isBlocked(player.getX() - 1, player.getY())) {
					// if (map.getSquareValue(player.getX() - 1, player.getY())
					// != 1
					// && map.getSquareValue(player.getX() - 1, player.getY())
					// != 7) {
					player.moveLeft();
					playerAnim(MOVE_LEFT);
					checkBattle();
					checkMapTransition();
					// }
				}
			}
		}

		if (input.isKeyPressed(Input.KEY_D)) {
			if ((player.getX() + 1) < 20) {
				if (!isBlocked(player.getX() + 1, player.getY())) {
					// if (map.getSquareValue(player.getX() + 1, player.getY())
					// != 1
					// && map.getSquareValue(player.getX() + 1, player.getY())
					// != 7) {
					player.moveRight();
					playerAnim(MOVE_RIGHT);
					checkBattle();
					checkMapTransition();
					// }
				}
			}
		}

	}

	@Override
	public int getID() {
		return ID;
	}
}
